import pygame
import math
import flame, weapon

pygame.init()

class enemy_obj(pygame.sprite.Sprite):

    SPARK_INTV = 1
    KEEP_DISTANCE = 60
    
    def __init__(self, screen_size, position, sub_type, motion, players):
        
        super(enemy_obj, self).__init__(self.containers)
        self.screen_size = screen_size
        self.screen_width = screen_size[0]
        self.screen_height = screen_size[1]
        self.sub_type = sub_type
        self.motion = motion
        self.flame_spark_intv = self.SPARK_INTV     #spark evry SPARK_INTV frame
        self.step_counter = 0                       #count how many step does the obj move
        self.target = None                          #Target(s) that will be locked/attacked by enemy_obj
        
        self.isboss = False

        self.players = players
        self.angel = 0
        self.fire_intv = 0
        self.firing = 0
        self.can_fire = False
        
        if (self.sub_type == 1):
            self.hp = 10
            self.score = 100
            self.exp = 50
            self.attack_mode = 0
            self.attack_area = None
#            self.power = 0
            self.norm_image = pygame.image.load("images/e1.png")
            self.accl_image = pygame.image.load("images/e1accel.png")
            self.image = self.norm_image
            #self._image = self.image
            self.rect = self.image.get_rect(center = (position))
            self.rect = self.rect.move(0, -self.rect.height / 2)
            self.speed = 8
            
        elif (self.sub_type == 2):
            self.hp = 20
            self.score = 200
            self.exp = 100
            self.attack_mode = 0
            self.attack_area = None
#            self.power = 0
            self.norm_image = pygame.image.load("images/e2.png")
            self.accl_image = pygame.image.load("images/e2accel.png")
            self.image = self.norm_image
            #self._image = self.image
            self.rect = self.image.get_rect(center = (position))
            self.rect = self.rect.move(0, -self.rect.height / 2)
            self.speed = 8

        elif (self.sub_type == 3):
            self.hp = 5
            self.score = 15
            self.exp = 15
            self.attack_mode = 0
            self.attack_area = None
#            self.power = 0
            self.norm_image = pygame.image.load("images/e3.png")
            self.accl_image = pygame.image.load("images/e3accel.png")
            self.image = self.norm_image
            #self._image = self.image
            self.rect = self.image.get_rect(center = (position))
            self.rect = self.rect.move(0, -self.rect.height / 2)
            self.speed = 8

        elif (self.sub_type == 4):
            self.hp = 5
            self.score = 15
            self.exp = 15
            self.attack_mode = 0
            self.attack_area = pygame.Rect(0, 0, 600, 600)      # create an attack area
            self.attack_area.center = position
            self.fire_intv = 10
            self.firing = self.fire_intv
            self.can_fire = True
#            self.power = 0
            self.norm_image = pygame.image.load("images/e4.png")
            self.accl_image = pygame.image.load("images/e4accel.png")
            self.image = self.norm_image
            #self._image = self.image
            self.rect = self.image.get_rect(center = (position))
            self.rect = self.rect.move(0, -self.rect.height / 2)
            self.speed = 8

        elif (self.sub_type == 5):
            self.hp = 5
            self.score = 15
            self.exp = 15
            self.attack_mode = 0
            self.attack_area = None
            self.fire_intv = 10
            self.firing = self.fire_intv
            self.can_fire = True
#            self.power = 0
            self.norm_image = pygame.image.load("images/e3.png")
            self.accl_image = pygame.image.load("images/e3accel.png")
            self.image = self.norm_image
            #self._image = self.image
            self.rect = self.image.get_rect(center = (position))
            self.rect = self.rect.move(0, -self.rect.height / 2)
            self.speed = 8

        elif (self.sub_type == 20):         #boss 1#
            self.hp = 15
            self.score = 10
            self.exp = 1500
            self.attack_mode = 0
            self.attack_area = pygame.Rect(0, 0, 600, 600)
            self.attack_area.center = position
#            self.power = 0
            self.norm_image = pygame.image.load("images/boss1.png")
            self.accl_image = pygame.image.load("images/boss1accel.png")
            self.image = self.norm_image
            #self._image = self.image
            self.rect = self.image.get_rect(center = (position))
            self.rect = self.rect.move(0, -self.rect.height / 2)

            self.move_step = 30
            self.isboss = True
            
            self.speed = 8

        else:
            pass

    def attack(self):
        if (self.can_fire):
            if (self.target):

                if (self.firing == 0):
                    print "Do fire!"
                    dx = self.rect.centerx - self.target.rect.centerx
                    dy = self.rect.centery - self.target.rect.centery

                    if (dx != 0):
                        speed = 15
                        l = float(dy) / dx
                        speed_x = math.sqrt((float(speed ** 2) / float(1 + l ** 2)))
                        speed_y = abs(l) * speed_x
                        if (dx > 0):
                            speed_x = -speed_x

                        if (dy > 0):
                            speed_y = -speed_y

                    else:
                        speed_x = 0
                        speed_y = 15 * abs(dy)/dy

                    self.firing = self.fire_intv
                    weapon.enemy_shot_obj(self.screen_size, speed_x, speed_y, (self.rect.centerx,self.rect.centery), self, 1) #Here 3 is a magic number
                else:
                    self.firing -= 1
            else:
                if (self.firing == 0):
#                    print "Do fire!"
                    self.firing = self.fire_intv
                    weapon.enemy_shot_obj(self.screen_size, 0, 15, (self.rect.centerx,self.rect.centery), self, 1) #Here 3 is a magic number
                else:
                    self.firing -= 1
                pass

    def detect_lock(self):
        if (self.attack_area is None):
            return
        
        if (self.target is None):
            nearest_distance = -1
            self.attack_area.center = self.rect.center
            for p in self.players:
                if (p.rect.colliderect(self.attack_area)):
                    cur_distance = self.get_distance(p.rect)
                    if (nearest_distance < 0 or cur_distance < nearest_distance):
                        nearest_distance = cur_distance
                        self.target = p

            print "lock: p",p.player_num

    def crashed(self):
        self.kill()
        self.hp = 0
        flame.explosion(self.rect.center)
        #flame...

    def destoried(self, oponent): #called by the shot that hit the obj
        self.hp -= oponent.power
        if (self.hp <= 0):
            oponent.belong_to.score += self.score
            oponent.belong_to.exp += self.exp
            oponent.belong_to.exp_update()
            print "Player ",oponent.belong_to.player_num," score: ",oponent.belong_to.score," exp: ",oponent.belong_to.exp
            self.crashed()

    def move(self):
        if (self.motion == 1):  # move forward
            if (self.rect.top + self.speed >= self.screen_height):
                pygame.sprite.Sprite.kill(self)
            else:
                self.rect = self.rect.move(0, self.speed)

        elif (self.motion == 2):    # move controled by sin
            MAX_MOVE_RANGE = 7
            if (self.rect.top + self.speed >= self.screen_height):
                pygame.sprite.Sprite.kill(self)
            else:
                x_speed = MAX_MOVE_RANGE * math.sin(self.step_counter)
                self.rect = self.rect.move(x_speed, self.speed)
                self.step_counter += 0.1

        elif (self.motion == 3):    # move controled by -sin
            MAX_MOVE_RANGE = 7
            if (self.rect.top + self.speed >= self.screen_height):
                pygame.sprite.Sprite.kill(self)
            else:
                x_speed = - MAX_MOVE_RANGE * math.sin(self.step_counter)
                self.rect = self.rect.move(x_speed, self.speed)
                self.step_counter += 0.1

        elif (self.motion == 4):    # move controled by cos
            MAX_MOVE_RANGE = 7
            if (self.rect.top + self.speed >= self.screen_height):
                pygame.sprite.Sprite.kill(self)
            else:
                x_speed = MAX_MOVE_RANGE * math.cos(self.step_counter)
                self.rect = self.rect.move(x_speed, self.speed)
                self.step_counter += 0.1

        elif (self.motion == 5):    # move controled by -cos
            MAX_MOVE_RANGE = 7
            if (self.rect.top + self.speed >= self.screen_height):
                pygame.sprite.Sprite.kill(self)
            else:
                x_speed = - MAX_MOVE_RANGE * math.cos(self.step_counter)
                self.rect = self.rect.move(x_speed, self.speed)
                self.step_counter += 0.1

        elif (self.motion == 6):    # Tracing movment
            if (self.target is None):
                if (self.rect.top + self.speed >= self.screen_height):
                    self.kill()
                else:
                    self.rect = self.rect.move(0, self.speed)
            else:
                dx = self.rect.centerx - self.target.rect.centerx
                dy = self.rect.centery - self.target.rect.centery

#                print "dx: ",dx," dy ",dy

                if (dx != 0):
                    l = dy / dx
                    self.angel = math.fabs(math.atan(l))

                    if (dx < 0 and dy < 0):
                        self.angel = -self.angel
                    elif (dx < 0 and dy >= 0):
                        self.angel = -(math.pi - self.angel)
                    elif (dx > 0 and dy < 0):
                        pass
                    elif (dx > 0 and dy >= 0):
                        self.angel = math.pi - self.angel
                        pass
                    
                    speed_x = math.sqrt(self.speed ** 2 / (1 + l ** 2))

                else:
                    if (dy < 0):
                        self.angel = 0
                    else:
                        self.angel = math.pi
                    speed_x = 0

                speed_y = 5

#                self.iamge = pygame.transform.rotate(self.image, angel)

                if (self.rect.centery <= self.target.rect.centery + self.KEEP_DISTANCE):

                    if (self.rect.centerx + speed_x <= (self.target.rect.centerx - self.KEEP_DISTANCE)):
                        self.rect = self.rect.move(speed_x, 0)
                    elif (self.rect.centerx - speed_x >= (self.target.rect.centerx + self.KEEP_DISTANCE)):
                        self.rect = self.rect.move(-speed_x, 0)

                    self.rect = self.rect.move(0,self.speed * 2)

                else:
#                    self.can_fire = True
                    self.rect = self.rect.move(0,speed_y)

                pass

        elif (self.motion == 10):   # 'T' moving

            MINIX = 128
            MAXIX = 384
            
            if (self.move_step):
                if (self.rect.top + self.speed >= self.screen_height):
                    pygame.sprite.Sprite.kill(self)
                else:
                    self.rect = self.rect.move(0, self.speed)

                self.move_step -= 1

            else:
                if (self.speed >= 0):
                    if (self.rect.left - self.speed >= MINIX):
                        self.rect.left -= self.speed
                    else:
                        self.rect.left = MINIX
                        self.speed = -self.speed
                else:
                    if (self.rect.right - self.speed <= MAXIX):
                        self.rect.right -= self.speed
                    else:
                        self.rect.right = MAXIX
                        self.speed = -self.speed
                
                
            pass
                
        else:
            pass

    def draw(self, screen):
        screen.blit(self.image, self.rect)

    def isalived(self):
        return self.hp

    def isbossed(self):
        return self.isboss

    def get_distance(self, obj_rect):
        return math.sqrt(abs(self.rect.centerx - obj_rect.centerx) ** 2
                         + abs(self.rect.centery - obj_rect.centery) ** 2)

    def rotate(self):       # Useless yes...
        center = self.rect.center
        self.image = pygame.transform.rotozoom(self.image, self.angle, 1.0)
        self.rect = self.image.get_rect()
        self.rect.center = center

    def update(self):
        if (self.flame_spark_intv == 0):
            self.flame_spark_intv = self.SPARK_INTV
            self.image = self.accl_image
        else:
            self.flame_spark_intv -= 1
            self.image = self.norm_image

        #self._image = self.image
        
        self.move()

        self.detect_lock()

        self.attack()
